package org.example;

import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

/**
 * HBase 的 API中，将DDL和DML分别封装成Table和Admin对象
 * Table 代表为DML，数据管理
 * Admin 代表DDL，表格操作
 */
public class HBaseDDL {

    //声明静态属性
    public static Connection connection
            = HBaseConnection.connection;

    /**
     * 创建命名空间
     * @param namespace 命名空间
     */
    public static  void createNamespace(String namespace) throws IOException {

        // admin的连接是轻量级，不是线程安全的，不推荐池化和缓存
        Admin admin = getAdmin();
        NamespaceDescriptor.Builder builder = NamespaceDescriptor.create(namespace);
        builder.addConfiguration("user","pop");
        try {
            admin.createNamespace(builder.build());
        } catch (IOException e) {
            System.out.println("表空间存在");
            e.printStackTrace();
        }

        //关闭
        admin.close();
    }

    /**
     * 判断表格是否存在
     * @param namespace 命名空间
     * @param tableName 表名
     * @return true 标识存在 false 不存在
     */
    public static boolean isTableExists(
            String namespace,String tableName
    ) throws IOException {
        Admin admin = getAdmin();
        boolean b = false;
        try {
            b = admin.tableExists(TableName.valueOf(namespace, tableName));
            if(admin!=null){
                admin.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return b;

    }

    /**
     * 创建表格
     * @param namespace 命名空间
     * @param tableName 表格名
     * @param columnFamilies 列簇
     */
    public static void createTable(
            String namespace,
            String tableName,
            String... columnFamilies

    ) throws IOException {
        if(columnFamilies.length==0){
            System.out.println("列不能为空");
            return;
        }
        if(!isTableExists(namespace, tableName)){
            System.out.println("表格不存在");
            return;
        }
        Admin admin = getAdmin();

        TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(
                TableName.valueOf(namespace, tableName)
        );

        for (String columnFamily : columnFamilies) {
            // 创建列簇描述
            ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(
                    Bytes.toBytes(columnFamily)
            );
            // 对应当前列族增加参数 设置VERSION
            columnFamilyDescriptorBuilder.setMaxVersions(3);
            ColumnFamilyDescriptor columnFamilyDescriptor = columnFamilyDescriptorBuilder.build();
            // 添加参数
            tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
        }
        TableDescriptor descriptor = tableDescriptorBuilder.build();
        try {
            admin.createTable(descriptor);
        } catch (IOException e) {
            System.out.println("表格已经存在");
            e.printStackTrace();
        }

        admin.close();
    }

    /**
     * 修改表一个列簇的版本
     * @param namespace 表空间
     * @param tableName 表名
     * @param columnFamilies    列簇名称
     * @param version 版本
     */
    public static void modifyTable(
            String namespace,
            String tableName,
            String columnFamilies,
            int version
    ) throws IOException {
        if(!isTableExists(namespace, tableName)){
            System.out.println("表格不存在");
            return;
        }
        Admin admin = getAdmin();

        // 修改的需要将你想要修改的东西传入才可以修改
        // 如果重新创建也算不上修改
        // 获得想要修改的表格描述
        TableDescriptor descriptor = admin.getDescriptor(TableName.valueOf(namespace, tableName));
        TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(descriptor);
        // 在原有的基础上修改
        ColumnFamilyDescriptor columnFamily = descriptor.getColumnFamily(Bytes.toBytes(columnFamilies));
        // 如果这里填写的是新的参数，老的参数会初始化
        ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(columnFamily);
        columnFamilyDescriptorBuilder.setMaxVersions(version);
        tableDescriptorBuilder.modifyColumnFamily(columnFamilyDescriptorBuilder.build());
        try {
            admin.modifyTable(tableDescriptorBuilder.build());
        } catch (IOException e) {
            e.printStackTrace();
        }

        admin.close();
    }

    /**
     * 删除表格
     * @param namespace 命名空间
     * @param tableName 表格
     * @return  是否删除成功
     */
    public static boolean deleteTable(
            String namespace,
            String tableName
    ) throws IOException {
        if (!isTableExists(namespace, tableName)){
            System.out.println("表不存在");
            return false;
        }
        Admin admin = getAdmin();
        try {
            TableName tn = TableName.valueOf(namespace, tableName);
            admin.disableTable(tn);
            admin.deleteTable(tn);
        } catch (IOException e) {
            e.printStackTrace();
        }

        admin.close();
        return true;
    }

    private static Admin getAdmin() throws IOException {
        return connection.getAdmin();
    }



    public static void main(String[] args) throws IOException {
//        createNamespace("bigbig");
//        System.out.println(isTableExists("default","stu"));
//        createTable("bigbig","student",
//                "age","name");

//        modifyTable("bigbig",
//                "student",
//                "age",5);

        deleteTable("bigbig","student");

        HBaseConnection.close();
    }

}
